package br.com.felix.fwt.ui;

import java.io.PrintWriter;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

import br.com.felix.fwt.ui.css.Border;
import br.com.felix.fwt.ui.css.BorderStyle;
import br.com.felix.fwt.ui.css.BorderWidth;
import br.com.felix.fwt.ui.css.Color;
import br.com.felix.fwt.ui.css.Colors;
import br.com.felix.fwt.ui.css.Cursor;
import br.com.felix.fwt.ui.css.Display;
import br.com.felix.fwt.ui.css.Overflow;
import br.com.felix.fwt.ui.css.PercentSize;
import br.com.felix.fwt.ui.css.Position;
import br.com.felix.fwt.ui.css.Style;
import br.com.felix.fwt.ui.exception.ComponentRenderException;
import br.com.felix.fwt.ui.javascript.Javascript;

public class TabbedPanel extends BaseComponent {
	
	private static final long serialVersionUID = -7117484694851958244L;
	
	private LinkedHashMap<String, Panel> panels;
	
	public int contentTopCorrection = 0;
	
	public int contentHeight = 400;
	
	public Color tabColor = new Color(Colors.WHITE);
	
	public Color tabFontColor = new Color(Colors.BLACK);
	
	public Color focusedTabColor = new Color(Colors.WHITE);;
	
	public Color focusedTabFontColor = new Color(Colors.BLACK);
	
	public BorderWidth borderWidth;
	
	public Color borderColor;
	
	public int tabsPerLine = 0;
	
	public Style tabStyle;
	
	
	{
	    this.cssClass = "fwttabbedpanel";
	}

	public TabbedPanel(Form parent) {
		panels = new LinkedHashMap<String, Panel>();
		tabStyle = new Style();
		tabStyle.cursor = Cursor.POINTER;
		tabStyle.padding = new int[] { 0, 5, 0, 5 };
		setValue("0");
		
		Javascript js = new Javascript() {
            @Override
            public String script() {
                return "closeAll();";
            }
        };
        parent.executeJavascript(js);
	}
	


	public void addTab(String title, Panel content) {
		super.add(content);
		content.setName("content_"+panels.size());
		panels.put(title, content);
	}
	


	@Override
	public void write(PrintWriter out) throws ComponentRenderException {
		if(!authorized()) return;
		StringBuilder closeAllScript = new StringBuilder();
		StringBuilder onclickScript;
		String componentName = getName();
	    
		closeAllScript.append("<script type=\"text/javascript\">\n function closeAll(){ \n var temp; \n");
		
		out.write("\n<div id=\"div_");
		out.write(componentName);
		out.write("\" class=\"");
		out.write(cssClass);
		out.write("\" ");
		if(style!=null){
			out.write(style);
		}
		out.write(" >");
		out.write("<input type=\"hidden\" name=\"");
		out.write(componentName);
		out.write("\" value=\"");
		out.write(getValue());
		out.write("\">");
		
		Border tabBorder = new Border();
		tabBorder.borderStyle(BorderStyle.SOLID);
		tabBorder.borderWidth(this.borderWidth != null ? borderWidth : BorderWidth.THIN);
		if (this.borderColor != null){
			tabBorder.borderColors(this.borderColor);
		}
		tabStyle.border = tabBorder;
		Style contentStyle = new Style();
		contentStyle.width = new PercentSize(100);
		contentStyle.height(contentHeight);
		contentStyle.top(0);
		contentStyle.position = Position.RELATIVE;
		contentStyle.border = tabBorder;
		contentStyle.overflow = Overflow.AUTO;
		contentStyle.display = Display.NONE;
		Set<String> keySetPanels = panels.keySet();
		out.write("\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n");
		int i = 0;
		int firstLine = 0;
		int resto = 0;
		if (tabsPerLine > 0) {
			resto = keySetPanels.size() % tabsPerLine;
			if (resto > 0) {
				firstLine = tabsPerLine - resto;
				out.write("\n<tr>");
			}
		}
		Panel panel;
		for (String title : keySetPanels) {
			if (i == firstLine) {
				for (int count = 0; count < resto; count++) {
					out.write("\n<td>&nbsp;</td>");
					i++;
				}
				if (resto > 0)out.write("\n</tr>"); 
				out.write("\n<tr>");
			}
			panel = panels.get(title);
			closeAllScript.append(panel.hide().toString()).append("\n");
			out.write("\n<td id=\"tab");
			out.write(String.valueOf(i));
			closeAllScript.append("\n temp = document.getElementById('tab")
			              .append(i)
			              .append("'); \n temp.style.color='")
			              .append(tabFontColor)
			              .append("'; \n temp.style.backgroundColor='")
			              .append(tabColor)
			              .append("';");
			out.write("\" ");
			out.write(tabStyle.toString());
			onclickScript = new StringBuilder("onclick=\"");
			onclickScript.append("document.forms[0].")
			             .append(componentName)
			             .append(".value=")
			             .append(i).append(";closeAll();");
			out.write(onclickScript.toString() + "\"");
			out.write(">");
			out.write(title);
			out.write("\n</td>");
			i++;
			if (tabsPerLine > 0 && i % tabsPerLine == 0) {
				out.write("\n</tr>\n<tr>");
			}
		}
		closeAllScript.append("\n var selectedTab;\n selectedTab = document.forms[0].")
		              .append(componentName)
		              .append(".value; \n temp = document.getElementById('tab'+selectedTab); \n temp.style.color='")
		              .append(focusedTabFontColor)
		              .append("'; \n temp.style.backgroundColor='")
		              .append(focusedTabColor)
		              .append("'; \n temp = document.getElementById('content_'+selectedTab); \n temp.style.display='block';")
		              .append("\n } \n </script>");
		
		out.write("\n</tr>\n</table>");
		out.write(closeAllScript.toString());

		for (Panel p: panels.values()) {
			p.setStyle(contentStyle);
			p.write(out);
		}
		out.write("\n</div>");
	}
	


	public void showTab(String tabName) {
	    Iterator<String> it = panels.keySet().iterator();
        int i = 0;
        while (it.hasNext()) {
            if (tabName.equals(it.next())) {
                setValue(String.valueOf(i));
                break;
            }
            i++;
        }
	}
	


	/**
	 * @param tabName is the title of the tab that you wish to retrive its
	 * contents. Obtains the panel that is the content of the tab which name was
	 * informed.
	 * @return the content of the desired tab.
	 */
	public Panel getTab(String tabName) {
		return panels.get(tabName);
	}



	/**
	 * @param tabName is the title of the tab that you wish to remove.
	 * */
	public void removeTab(String tabName) {
		Panel tab = panels.get(tabName);
		super.remove(tab);
		panels.remove(tab);
	}
}
